using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

using Microsoft.Xna.Framework;

using Librarinth;

namespace SunwellRenderer.Camera
{
	public struct CameraData
	{
		public int SpatialIndex;
		public float Near,Far,FOV,AspectRatio;
		public CameraData(int spatialIndex,float fov,float aspectRatio,float near,float far)
		{
			SpatialIndex	= spatialIndex;
			AspectRatio	= aspectRatio;
			Near	= near;
			Far	= far;
			FOV	= fov;
		}
	}

	public abstract class CameraModule<D> : Module<D>
	{
		public abstract Matrix CameraWorld(int index);
		protected abstract Matrix Projection(ref D data);

		public Matrix View(int index)
		{ return Matrix.Invert(CameraWorld(index)); }
		public Matrix Projection(int index)
		{ return Projection(ref Datas[index]); }
		public Matrix ViewProjection(int index)
		{ return View(index) * Projection(index); }
	}

	public struct OrthoData
	{
		public int SpatialIndex;
		public float Near,Far,FOV,AspectRatio;
	}
	public class OrthographicCamera : CameraModule<OrthoData>
	{
	}

	public class PerspectiveCamera : CameraModule<CameraData>
	{
		public override Matrix CameraWorld(int index)
		{
			var spatialIndex	= Datas[index].SpatialIndex;
			return SunwellMain.Instance.SpatialModule.Datas[spatialIndex].World;
		}

		protected override Matrix Projection(ref CameraData data)
		{ return Matrix.CreatePerspectiveFieldOfView(data.FOV,data.AspectRatio,data.Near,data.Far); }

		protected override void Alloc(ref CameraData data)
		{
			data	= default(CameraData);
			data.SpatialIndex	= -1;
		}
		protected override void Free(ref CameraData data)
		{
			data	= default(CameraData);
			data.SpatialIndex	= -1;
		}
	}
}
